#pragma once
#include <sstream>


#include "../SQLExprImpl.h"
// #include "../../visitor/SQLASTVisitor.h"
#include "../SQLName.h"
#include "../SQLObject.h"
// #include "../statement/SQLTableSource.h"

class SQLASTVisitor;

class SQLIdentifierExpr : virtual public SQLExprImpl, virtual public SQLName
{
private:
  string_ptr name;

  string_ptr lowerName;
  SQLObject_ptr resolvedOwnerObject;
  SQLObject_ptr resolvedColumn;
  long hashCode64_;

public:
  static string_ptr class_;

  SQLIdentifierExpr();
  virtual ~SQLIdentifierExpr();

  SQLIdentifierExpr(string_ptr name);
  SQLIdentifierExpr(string_ptr name, long hash_lower)
  {
    this->name = name;
    this->hashCode64_ = hash_lower;
  }
  SHAREDOBJECT(SQLIdentifierExpr);
  string_ptr getSimleName();

  string_ptr getName();

  void setName(string_ptr name);

  string_ptr getLowerName();

  void setLowerName(string_ptr lowerName);

  void output(std::stringstream * buf);
  // int hashCode();
  // BOOL_ptr equals(Object obj);
  string_ptr getSimpleName();

  // SQLName_ptr clone();
  virtual SQLObject_ptr clone();
  long nameHashCode64();

  long hashCode64();

  SQLObject_ptr getResolvedColumn() override;
  // SQLTableSource_ptr  getResolvedTableSource();

  bool containsAttribute(string_ptr name){};
  // void addBeforeComment(string_list_ptr comments){};
  string_list_ptr getAfterCommentsDirect(){};
  string_list_ptr getBeforeCommentsDirect(){};
  void addAfterComment(string_ptr comment){};
  void addAfterComment(string_list_ptr comments){};
  bool hasBeforeComment(){};
  bool hasAfterComment(){};

  BOOL_ptr nameEquals(string_ptr name);
  string_ptr normalizedName();

  SQLTableSource_ptr getResolvedTableSource();
  void setResolvedTableSource(SQLTableSource_ptr resolvedTableSource);
  SQLObject_ptr getResolvedOwnerObject();
  void setResolvedOwnerObject(SQLObject_ptr resolvedOwnerObject);
  void setResolvedColumn(SQLColumnDefinition_ptr resolvedColumn);
  void setResolvedColumn(SQLSelectItem_ptr selectItem);
  SQLSelectItem_ptr getResolvedSelectItem();
  SQLObject_ptr getResolvedColumnObject();
  void setResolvedDeclareItem(SQLDeclareItem_ptr resolvedDeclareItem);
  void setResolvedParameter(SQLParameter_ptr resolvedParameter);
  SQLParameter_ptr getResolvedParameter();
  // void setResolvedParameter(SQLParameter_ptr resolvedParameter);
  SQLDeclareItem_ptr getResolvedDeclareItem();
  SQLIdentifierExpr_ptr simplify();

protected:
  void accept0(SQLASTVisitor_ptr visitor);
};

